package com.czy.plugin.util;

import com.google.common.base.Charsets;
import com.google.common.io.Files;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.String.format;

/**
 * 为类字段生成@ApiModelProperty注解(需要其他注解自己调整)@ApiModelProperty(name = "XXX",value = "YYYYYY",required = ???)
 * 读取字段名填充到XXX
 * 读取注释填充到YYYYYY
 * 根据 @Not 判断required的ture or false
 * <p>
 * 注:以下出现问题的情况基本是代码不规范导致(比如字段或类没有注释)
 * 1.虽能减少99%的人工处理,提交代码前最好编译下
 * 2.出现这种情况value = "VALUEHOLDER",required = REQUIREHDOLGER 原因是字段没有加注释,无法判断是否是开发者不规范或者不需要这字段,编译时可暴露这问题
 * 3.重复调用会替换原有@ApiModelProperty @ApiModel(当然可以做成可保留,有需要自己优化)
 *
 * @author hongjiawei
 * @date 2019/12/29 11:11
 */
public class ApiHelper {

    public static final Pattern HEAD_PATTERN = Pattern.compile("[\\s\\S]*?public class (.*?)\\{");

    public static final Pattern CLASS_NAME_PATTERN = Pattern.compile("/\\*\\*([\\s\\S]*?)(@*?)\\*/([\\s\\S]*?)(public class (.*?))\\{");

    /**
     * 单个文件
     *
     * @param fileName
     * @throws IOException
     */
    public static byte[] setApiModel(String fileName) throws IOException {
        String ori = readFileContent(fileName);
        String s = ori
                .replaceAll("import io.swagger.annotations.ApiModel;\r\n", "")
                .replaceAll("import io.swagger.annotations.ApiModelProperty;\r\n", "")
                .replaceAll(".*?@ApiModelProperty[\\s\\S].*?\r\n", "")
                .replaceAll("(.*?)@ApiModel[\\s\\S].*?\r\n", "$1")
                .replaceAll("([^/])private (.*?) (.*?);",
                        "$1@ApiModelProperty(name = \"$3\",value = \"VALUEHOLDER\")\r\n    private $2 $3;");
        //把头去掉
        Matcher matcherHeader = HEAD_PATTERN.matcher(s);
        String head = "";
        if (matcherHeader.find()) {
            head = matcherHeader.group(0);
            s = s.replace(matcherHeader.group(0), "");
            Matcher classNameMatcher = CLASS_NAME_PATTERN.matcher(head);

            if (classNameMatcher.find()) {
                String group = classNameMatcher.group(0);
                head = head.replace(group,
                        group.replace(
                                classNameMatcher.group(4),
                                format("@ApiModel(value = \"%s\")\r\n%s",
                                        classNameMatcher.group(1).replace("*", "")
                                                .replace("/", "")
                                                .replace("\r\n", "")
                                                .trim(), classNameMatcher.group(4))));
                head = head.replaceAll("(package .*?;\r\n\r\n)", "$1import io.swagger.annotations.ApiModel;\r\nimport io.swagger.annotations.ApiModelProperty;\r\n");
            }
        }

        String regex = "/\\*\\*([\\s\\S]*?)\\*/([\\s\\S]*?)@ApiModelProperty\\(name = \"(.*?)\",value = \"(.*?)\"\\)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(s);
        while (matcher.find()) {
            s = s.replace(matcher.group(0), matcher.group(0)
                    .replace("VALUEHOLDER", matcher.group(1)
                            .replace("/*", "")
                            .replace("\r\n", "")
                            .replace("*", "").trim()));
        }
        return (head + s).getBytes(Charsets.UTF_8);
    }

    /**
     * 逐行读取文件追加换行符
     *
     * @param fileName
     * @return
     * @throws IOException
     */
    private static String readFileContent(String fileName) throws IOException {
        List<String> strings = Files.readLines(new File(fileName), Charsets.UTF_8);
        StringBuffer sbf = new StringBuffer();
        strings.forEach(s -> {
            sbf.append(s).append("\r\n");
        });
        return sbf.toString();
    }

}
